package map
{
	import battle.MapItem;
	import battle.Soldier;
	
	import flash.display.Bitmap;
	import flash.display.DisplayObject;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	import loaders.DisplayLoader;
	import loaders.ILoader;
	import loaders.LoaderManager;
	import loaders.LoaderQueue;
	
	import manager.PathManager;
	
	import map.animation.AnimationManager;
	import map.animation.MapCenterAnimation;
	import map.data.Front;
	import map.data.Mapdata;
	import map.data.Obstacle;
	import map.data.RadCell;
	import map.geometry.RadLine;
	
	import spark.components.supportClasses.DisplayLayer;

	public class MapView extends BaseMapView
	{
		private var _mapInfo:MapInfo;
		private var _items:Vector.<MapItem>;
		private var _animationManager:AnimationManager;
		public function MapView(mapInfo:MapInfo,viewWidth:Number,viewHeight:Number)
		{
			super(viewWidth,viewHeight);
			_mapInfo = mapInfo;
			_items = new Vector.<MapItem>();
			_animationManager = new AnimationManager();
			loadData();
		}
		
		public function calcDamage(fromIndex:int,targetIndex:int,soldier:Soldier):Number
		{
			var fromCell:RadCell = _mapData.cells[fromIndex];
			var targetCell:RadCell = _mapData.cells[targetIndex];
			var dis:Number = fromCell.Distance_3d(targetCell);
			var damage:Number = soldier.getDamage(dis);
			if(damage>0)
			{
				var line:RadLine = new RadLine(fromCell.center,targetCell.center);
				for each(var obs:Obstacle in _mapData.obstacles)
				{
					if(line.intersect(obs.line))
					{
						damage -= damage*obs.weaken;
						if(damage<=0)
							return 0;
					}
				}
			}
			return 0;
		}
		
		public function calcPath(solder:Soldier,targetCell:RadCell):Vector.<RadCell>
		{
			var result:Vector.<RadCell> = new Vector.<RadCell>();
			if(!solder.currentCells)
			{
				solder.currentCells = getCellsByPosition(solder.info.position,solder.info.mobility,solder.info.unitMobility);
			}
			for each(var cell:RadCell in solder.currentCells)
			{
				if(cell == targetCell || cell.positionEqual(targetCell))
				{
					break;
				}
			}
			while(cell.parent)
			{
				result.push(cell);
				cell = cell.parent;
			}
			return result.reverse();
		}
		
		public function calcPathToPoint(soldier:Soldier,targetCell:RadCell):Vector.<Point>
		{
			var result:Vector.<Point> = new Vector.<Point>();
			var cells:Vector.<RadCell> = calcPath(soldier,targetCell);
			result.push(cells[0].center);
			for(var i:int=1;i<cells.length-1;i++)
			{
				var preCenter:Point = cells[i-1].center;
				var center:Point = cells[i].center;
				var nextCenter:Point = cells[i+1].center;
				if(Point.distance(preCenter,center)+Point.distance(center,nextCenter)-Point.distance(preCenter,nextCenter)>1)
				{
					result.push(center);
				}
			}
			result.push(cells[i+1].center);
			return result;
		}
		
		public function loadData():void
		{
			LoaderManager.Instance.loadEasy(PathManager.resloveMapDataPath(_mapInfo.id),onDataComplete);
		}
		
		public function addMapItem(item:MapItem):void
		{
			_items.push(item);
		}
		
		public function update():void
		{
			while(_itemLayer.numChildren>0){
				_itemLayer.removeChildAt(0);
			}
			var view:DisplayObject;
			for each(var item:MapItem in _items)
			{
				view = item.view;
				if(view)
				{
					_itemLayer.addChild(view);
				}
			}
			_animationManager.update();
		}
		
		override public function viewAt(point:Point,priority:int=1,tweenAble:Boolean=true):void
		{
			if(tweenAble)
			{
				_animationManager.addAnimation(new MapCenterAnimation(this,point,priority));
			}else
			{
				_animationManager.addAnimation(new MapCenterAnimation(this,point,priority,0));
			}
		}
		
		public function getBirthPoint():Point
		{
			return _mapData.birthpoints[0];
		}
		
		private function onDataComplete(loader:ILoader):void
		{
			var bytes:ByteArray = loader.content;
			var obj:Object = bytes.readObject();
			_mapData = Mapdata.decode(obj);
			for(var i:int=0;i<_mapData.fronts.length;i++)
			{
				var front:MapFrontItem = new MapFrontItem(_mapInfo.id,_mapData.fronts[i]);
				addMapItem(front);
			}
			dispatchEvent(new Event(Event.COMPLETE));
			loadResource();
		}
		
		public function loadResource():void
		{
			LoaderManager.Instance.loadEasy(PathManager.resloveMapBGPath(_mapInfo.id,_mapData.bgurl),onBgComplete);
			for each(var item:MapItem in _items)
			{
				item.loadResource();
			}
		}
		
		private function onBgComplete(loader:ILoader):void
		{
			_background = loader.content as Bitmap;
			addChildAt(_background,0);
		}
	}
}